package com.weifly.weistock.record.asset;

import com.weifly.weistock.core.chart.bo.ChartDataSetBO;
import com.weifly.weistock.core.chart.bo.ChartSerieBO;
import com.weifly.weistock.core.market.bo.StockDayBO;
import com.weifly.weistock.core.market.bo.StockKLineBO;
import com.weifly.weistock.core.util.WeistockUtils;
import com.weifly.weistock.record.asset.domain.AssetDayDto;
import com.weifly.weistock.record.asset.domain.AssetYearDto;
import org.apache.commons.lang3.StringUtils;

import java.text.DecimalFormat;
import java.util.*;

/**
 * 用户资产工具类
 *
 * @author weifly
 * @since 2019/9/24
 */
public class AssetUtils {

    public static void updateDayOfYear(AssetYearDto yearDto, AssetDayDto dayDto) {
        AssetDayDto targetDay = null;
        for (AssetDayDto dayInYear : yearDto.getDayList()) {
            if (dayInYear.getDay().equals(dayDto.getDay())) {
                // 同一天
                targetDay = dayInYear;
                break;
            }
        }

        if (targetDay == null) {
            yearDto.getDayList().add(dayDto);
            // 记录排序
            yearDto.getDayList().sort(Comparator.comparing(AssetDayDto::getDay));
        } else {
            targetDay.copyPropForm(dayDto);
        }
    }

    /**
     * 装入资产DataSet
     *
     * @param dataSet
     * @param dayList
     */
    public static void fillAssetDataSet(ChartDataSetBO dataSet, List<AssetDayDto> dayList) {
        if (dayList.isEmpty()) {
            return;
        }

        ChartSerieBO chartSerie = new ChartSerieBO();
        chartSerie.setName("资产");
        chartSerie.setType("line");
        double baseAsset = dayList.get(0).getAsset();
        DecimalFormat decimalFormat = new DecimalFormat("0.####");
        for (AssetDayDto dayDto : dayList) {
            dataSet.getPointList().add(dayDto.getDay());
            double rate = WeistockUtils.divide(dayDto.getAsset(), baseAsset);
            chartSerie.getDataList().add(Double.valueOf(decimalFormat.format(rate)));
        }
        dataSet.getSerieList().add(chartSerie);
    }

    /**
     * 加载数据列表，用于chart显示
     */
    public static List<StockDayBO> loadStockDayList(StockKLineBO stockKLineBO, String lowDay) {
        LinkedList<StockDayBO> dayList = new LinkedList<>();
        if (StringUtils.isBlank(lowDay)) {
            return dayList;
        }
        if (stockKLineBO.getDayList() == null) {
            return dayList;
        }
        Iterator<StockDayBO> dayIter = stockKLineBO.getDayList().iterator();
        while (dayIter.hasNext()) {
            StockDayBO dayBO = dayIter.next();
            if (lowDay.compareTo(dayBO.getDay()) <= 0) {
                dayList.add(dayBO);
            }
        }
        return dayList;
    }

    public static void fillStockDataSet(ChartDataSetBO dataSet, List<StockDayBO> stockDayList, String stockCode, String stockName) {
        if (stockDayList.isEmpty()) {
            return; // 无股票数据
        }
        if (dataSet.getPointList().isEmpty()) {
            return; // 无坐标数据
        }
        String basePoint = dataSet.getPointList().get(0);

        // 生成stockDayMap, 并寻找基准价格
        Map<String, StockDayBO> stockDayMap = new HashMap<>();
        StockDayBO baseDayBO = null;
        for (StockDayBO stockDayBO : stockDayList) {
            stockDayMap.put(stockDayBO.getDay(), stockDayBO);
            if (stockDayBO.getDay().compareTo(basePoint) >= 0) {
                if (baseDayBO == null) {
                    baseDayBO = stockDayBO; // 和basePoint最接近的数据
                }
            }
        }
        if (baseDayBO == null || baseDayBO.getClose() <= 0) {
            return; // 没有找到基准价
        }

        // 生成股票数据集
        double basePrice = baseDayBO.getClose();
        ChartSerieBO stockSerie = new ChartSerieBO();
        stockSerie.setName(StringUtils.isBlank(stockName) ? stockCode : stockName);
        stockSerie.setType("line");
        DecimalFormat decimalFormat = new DecimalFormat("0.####");
        for (Object point : dataSet.getPointList()) {
            StockDayBO dayBO = stockDayMap.get(point);
            double currPrice = 0;
            if (dayBO == null) {
                currPrice = basePrice;
            } else {
                currPrice = dayBO.getClose();
            }
            double rate = WeistockUtils.divide(currPrice, basePrice);
            stockSerie.getDataList().add(Double.valueOf(decimalFormat.format(rate)));
        }
        dataSet.getSerieList().add(stockSerie);
    }
}
